package com.qqq.chatservice.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.qqq.chatservice.domain.dto.MessageDTO;
import com.qqq.chatservice.domain.dto.SessionStatusDetailDTO;
import com.qqq.commoncore.utils.JsonUtil;
import com.qqq.commonredis.service.RedisService;
import jakarta.annotation.Resource;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

@Component
@Slf4j
public class ChatCacheService {

    @Resource
    private RedisService redisService;
    // ⽤户id-会话ids
    private static final String CHAT_ZSET_USER_PREFIX = "chat:zset:user:";
    // 会话id-会话状态详情
    private static final String CHAT_SESSION_PREFIX = "chat:session:";
    // 会话id-消息列表（zset）
    private static final String CHAT_ZSET_SESSION_PREFIX = "chat:zset:session:";

    /**
     * 新增用户下的一个新会话
     * @param userId
     * @param sessionId
     * @param lastSessionTime 排序规则：最后的会话时间
     */
    public void addUserSessionToCache(Long userId, Long sessionId, Long
            lastSessionTime) {
        try {
            String key = CHAT_ZSET_USER_PREFIX + userId;
            redisService.addMemberZSet(key, sessionId, lastSessionTime);
        } catch (Exception e) {
            log.error("新增⽤户-会话ids缓存时发⽣异常，key:{}",
                    CHAT_ZSET_USER_PREFIX + userId, e);
        }
    }

    /**
     * 获取用户下的会话列表
     * @param userId
     * @return
     */
    public Set<Long> getUserSessionsByCache(Long userId) {
        Set<Long> sessionIds = new HashSet<>();
        try {
            String key = CHAT_ZSET_USER_PREFIX + userId;
            sessionIds = redisService.getCacheZSetDesc(key, new
                    TypeReference<LinkedHashSet<Long>>() {});
            if (CollectionUtils.isEmpty(sessionIds)) {
                return new HashSet<>();
            }
        } catch (Exception e) {
            log.error("从缓存中获取⽤户-会话ids时发⽣异常，key:{}",
                    CHAT_ZSET_USER_PREFIX + userId, e);
        }
        return sessionIds;
    }

    /**
     * 缓存会话详细信息
     * @param sessionId
     * @param sessionStatusDetailDTO
     */
    public void cacheSessionStatusDetail(Long sessionId,
                                         SessionStatusDetailDTO sessionStatusDetailDTO) {
        try {
            String key = CHAT_SESSION_PREFIX + sessionId;
            redisService.setCacheObject(key,
                    JsonUtil.obj2string(sessionStatusDetailDTO));
        } catch (Exception e) {
            log.error("缓存会话状态详情时发⽣异常，key:{}", CHAT_SESSION_PREFIX
                    + sessionId, e);
        }
    }

    /**
     * 获取会话详细信息缓存
     *
     * @param sessionId
     * @return
     */
    public SessionStatusDetailDTO getSessionDTOByCache(Long sessionId) {
        SessionStatusDetailDTO sessionDTO = null;
        try {
            String key = CHAT_SESSION_PREFIX + sessionId;
            String str = redisService.getCacheObject(key, String.class);
            if (StringUtil.isBlank(str)) {
                return null;
            }
            sessionDTO = JsonUtil.string2Obj(str, SessionStatusDetailDTO.class);
        } catch (Exception e) {
            log.error("获取会话详细信息缓存时发生异常，sessionId:{}", sessionId, e);
        }
        return sessionDTO;
    }

    /**
     * 获取会话详细信息缓存
     * @param sessionId
     * @return
     */
    public SessionStatusDetailDTO getSessionStatusDetailByCache(Long
                                                                        sessionId) {
        SessionStatusDetailDTO resultDTO = null;
        try {
            String key = CHAT_SESSION_PREFIX + sessionId;
            String resultStr = redisService.getCacheObject(key, String.class);
            if (StringUtil.isBlank(resultStr)) {
                return null;
            }
            resultDTO = JsonUtil.string2Obj(resultStr,
                    SessionStatusDetailDTO.class);
        } catch (Exception e) {
            log.error("从缓存中获取会话状态详情异常，key:{}", CHAT_SESSION_PREFIX
                    + sessionId, e);
        }
        return resultDTO;
    }

    /**
     * 新增会话下的消息缓存
     * @param sessionId
     * @param messageDTO
     */
    public void addMessageDTOToCache(Long sessionId, MessageDTO messageDTO) {
        try {
            String key = CHAT_ZSET_SESSION_PREFIX + sessionId;
            redisService.addMemberZSet(key, messageDTO,
                    Long.parseLong(messageDTO.getMessageId()));
        } catch (Exception e) {
            log.error("新增会话id-消息列表缓存时发⽣异常，key:{}",
                    CHAT_ZSET_SESSION_PREFIX + sessionId, e);
        }
    }

    /**
     * 删除会话下消息缓存
     * @param sessionId
     * @param messageId
     */
    public void removeMessageDTOCache(Long sessionId, String messageId) {
        try {
            String key = CHAT_ZSET_SESSION_PREFIX + sessionId;
            redisService.removeZSetByScore(key, Long.parseLong(messageId),
                    Long.parseLong(messageId));
        } catch (Exception e) {
            log.error("删除会话下消息缓存时发⽣异常，key:{}, delMessageId:{}",
                    CHAT_ZSET_SESSION_PREFIX + sessionId, messageId, e);
        }
    }

    /**
     * 从缓存中获取会话
     * @param sessionId
     * @return
     */
    public Set<MessageDTO> getMessageDTOSByCache(Long sessionId) {
        Set<MessageDTO> messageSet = new HashSet<>();
        try {
            String key = CHAT_ZSET_SESSION_PREFIX + sessionId;
            messageSet = redisService.getCacheZSetDesc(key, new
                    TypeReference<LinkedHashSet<MessageDTO>>() {
                    });
            if (CollectionUtils.isEmpty(messageSet)) {
                return new HashSet<>();
            }
        } catch (Exception e) {
            log.error("从缓存中获取会话id-消息列表时发⽣异常，key:{}",
                    CHAT_ZSET_SESSION_PREFIX + sessionId, e);
        }
        return messageSet;
    }
}
